package ru.linnenson.darshana.infrastructure.services;

import com.google.common.collect.Lists;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import ru.linnenson.darshana.application.services.PhotoReader;
import ru.linnenson.darshana.application.services.PhysicTasksStoreService;
import ru.linnenson.darshana.application.services.StorageService;
import ru.linnenson.darshana.infrastructure.persistence.EntityNotFoundException;
import ru.linnenson.darshana.infrastructure.persistence.models.PhysicTaskStore;
import ru.linnenson.darshana.infrastructure.persistence.repositories.PhysicTaskPersistenceRepository;
import ru.linnenson.darshana.infrastructure.persistence.repositories.PhysicTaskPredicateBuilder;
import ru.linnenson.darshana.infrastructure.rest.dto.PhysicTasksCriteria;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor
public class PhysicTasksStoreServiceImpl implements PhysicTasksStoreService {

  private final PhotoReader photoReader;
  private final StorageService storageService;
  private final PhysicTaskPredicateBuilder physicTaskPredicateBuilder;
  private final PhysicTaskPersistenceRepository physicTaskPersistenceRepository;

  @Override
  public List<PhysicTaskStore> search(final PhysicTasksCriteria criteria, final Pageable pageable) {

    return Lists.newArrayList(
        physicTaskPersistenceRepository.findAll(physicTaskPredicateBuilder.build(criteria), pageable)
    );
  }

  @Override
  @Transactional
  public void addPhoto(final Integer taskId, final byte[] photo) {

    final PhysicTaskStore task = physicTaskPersistenceRepository.findById(taskId)
                                                                .orElseThrow(EntityNotFoundException::new);

    final String text = photoReader.read(photo);
    final String photoId = storageService.save(photo);

    final String fullText = StringUtils.hasText(task.getText()) ? (task.getText() + " " + text) : text;
    final List<String> allPhoto = CollectionUtils.isEmpty(task.getPhotoIds())
        ? new ArrayList<>()
        : task.getPhotoIds();

    allPhoto.add(photoId);

    task.setText(fullText);
    task.setPhotoIds(allPhoto);

    physicTaskPersistenceRepository.save(task);
  }

  @Override
  @Transactional
  public void addSolutionPhoto(final Integer taskId, final byte[] photo) {

    final String photoId = storageService.save(photo);
    final PhysicTaskStore task = physicTaskPersistenceRepository.findById(taskId)
                                                                .orElseThrow(EntityNotFoundException::new);

    final List<String> allPhoto = CollectionUtils.isEmpty(task.getSolutionPhotoIds())
        ? new ArrayList<>()
        : task.getSolutionPhotoIds();

    allPhoto.add(photoId);

    task.setSolutionPhotoIds(allPhoto);

    physicTaskPersistenceRepository.save(task);
  }

  @Override
  @Transactional
  public void deleteSolutionPhoto(final Integer taskId, final String photoId) {

    storageService.delete(photoId);

    final PhysicTaskStore task = physicTaskPersistenceRepository.findById(taskId)
                                                                .orElseThrow(EntityNotFoundException::new);

    task.getSolutionPhotoIds().remove(photoId);

    physicTaskPersistenceRepository.save(task);

    log.info("delete photo {} from task {}", photoId, taskId);
  }
}
